
#pragma once

#include "scanner.h"
#include "config.h"
#include <set>

namespace os
{
    typedef std::set<path>
        SetPath;
    typedef std::set<str>
        SetMask;

    void ScanDirectory(const path& absolute_path,
        const SetMask& exclude_files,
        const SetMask& exclude_dirs,
        const SetMask& include_files,
        const SetMask& include_dirs,
              SetPath& directories,
              SetPath& files,
        const bool regex = false
        );


    struct Scanner
    {
        typedef 
            bool (*UserFunction)(SetPath&);
        typedef 
            void (*ExitFromDirectory)(const path&);

        Scanner();
        virtual~Scanner(){}

        Scanner& ExcludeFileMask(const  str& mask);
        Scanner& ExcludeFileRegex(const str& regex);
        Scanner& ExcludeFileMask(const  SetMask& list_mask);
        Scanner& ExcludeFileRegex(const SetMask& list_regex);

        Scanner& ExcludeDirMask(const  str& mask);
        Scanner& ExcludeDirRegex(const str& regex);
        Scanner& ExcludeDirMask(const  SetMask& list_mask);
        Scanner& ExcludeDirRegex(const SetMask& list_regex);

        Scanner& IncludeFileMask(const  str& mask);
        Scanner& IncludeFileRegex(const str& regex);
        Scanner& IncludeFileMask(const  SetMask& list_mask);
        Scanner& IncludeFileRegex(const SetMask& list_regex);

        Scanner& IncludeDirMask(const  str& mask);
        Scanner& IncludeDirRegex(const str& regex);
        Scanner& IncludeDirMask(const  SetMask& list_mask);
        Scanner& IncludeDirRegex(const SetMask& list_regex);

        Scanner& ProcessedFiles(UserFunction func);
        Scanner& ProcessedDirectories(UserFunction func);
        Scanner& ProcessedExitFromDirectory(ExitFromDirectory func);

        void Search(const path& absolute_path);
    protected:
        virtual bool ProccessedFiles(SetPath& files)
            { (void) files; return false; }
        virtual bool ProccessedDirs(SetPath& dirs)
            { (void) dirs; return false; }
        virtual void LeaveDirectory(const path&)
            {}
    private:
        SetMask mExcludeF;
        SetMask mExcludeD;
        SetMask mIncludeF;
        SetMask mIncludeD;

        ExitFromDirectory mExit;
        UserFunction mProcF;
        UserFunction mProcD;
    };


/*
    struct ScanDirectory : IScanner
    {
        ScanDirectory(){}
        virtual ~ScanDirectory(){}

    public:


    protected:
        virtual void Invalid(const path&){}
        virtual void Begin(const path&){}
        virtual void End(const path&){}
        virtual bool Directory(const path&){ return false; }
        virtual void File(const path&){}
        virtual void EnterDirectory(const path&){}
        virtual void LeaveDirectory(const path&){}
    };
    */

}//namespace os

